

module frv_isu_top (
    input                       clk             ,
    input                       rst_n           ,
    // Program Downloader Interface
    input                       pd_rst          ,
    // Flush Interface
    input                       exp_flush       , // Exception Flush
    input [5:0]     exp_flush_tid   , // Exception Flush ID
    input                       bru_flush       , // Branch Prediction failed Flush
    // input [5:0]     bru_flush_tid   , // Branch Prediction Flush ID
    // ==========================================================================
    // Issue Queue Interface
    output                      isu_ready       , // Issue Queue Ready , when issue queue is full , isq_ready will be pull up
    input                       isq_wreq        , // Issue Queue Request
    input [31:0]                isq_inst_data   ,
    input  [5:0]    isq_inst_id     ,
    input                       isq_exp_vld     ,
    input [4:0]                 isq_exp_code    ,
    input [31:0]                isq_pc_data     ,
    //ALU Control Interface
    input                       isq_alu_vld     ,
    input                       isq_alu_land    ,
    input                       isq_alu_lor     ,
    input                       isq_alu_lxor    ,
    input                       isq_alu_sll     ,
    input                       isq_alu_srl     ,
    input                       isq_alu_sra     ,
    input                       isq_alu_add     ,
    input                       isq_alu_sub     ,
    input                       isq_alu_slt     ,
    input                       isq_alu_unsign  ,
    //Branch Control Interface
    input                       isq_bru_vld     ,
    input                       isq_bru_beq     ,
    input                       isq_bru_bne     ,
    input                       isq_bru_blt     ,
    input                       isq_bru_bge     ,
    input                       isq_bru_jal     ,
    input                       isq_bru_jalr    ,
    input [31:0]                isq_bp_taddr    , // bp target addr
    input                       isq_bp_taken    , // bp taken
    input [3:0]                 isq_bp_bhtv     , // BHT Entry Value
    input [31:0]                isq_bp_phtv     , // PHT Entry Value
    //LSU Control Interface
    input                       isq_lsu_vld     ,
    input                       isq_lsu_unsign  ,
    input                       isq_lsu_load    ,
    input                       isq_lsu_store   ,
    input                       isq_lsu_word    ,
    input                       isq_lsu_half    ,
    input                       isq_lsu_byte    ,
    //MDU Control Interface
    //TODO
    //CSR Control Interface
    input                       isq_csr_vld     ,
    input                       isq_csr_write   ,
    input                       isq_csr_set     ,
    input                       isq_csr_clr     , // CSR Clear
    //Operation number Interface
    input                       isq_rs1_vld     ,
    input[5:0]      isq_rs1_ind     ,
    input                       isq_rs1_rdy     ,    
    input                       isq_rs1_type    ,
    input                       isq_rs2_vld     ,
    input[5:0]      isq_rs2_ind     ,
    input                       isq_rs2_rdy     ,    
    input                       isq_rs2_type    ,
    input                       isq_imm_vld     ,
    input [31:0]                isq_imm_data    , // here we can compress the width
    input                       isq_rd_vld      ,
    input [4:0]                 isq_rd_ind      , // Reg Destenation Index
    // input [5:0]     isq_rdm_ind     ,
    input                       isq_pc_used     , // jal and auipc will use the pc value    
    // ==========================================================================
    //ALU Interface 
    output                      alu_req         ,
    output                      alu_ctrl_land   ,
    output                      alu_ctrl_lor    ,
    output                      alu_ctrl_lxor   ,
    output                      alu_ctrl_sll    ,
    output                      alu_ctrl_srl    ,
    output                      alu_ctrl_sra    ,
    output                      alu_ctrl_add    ,
    output                      alu_ctrl_sub    ,
    output                      alu_ctrl_slt    ,
    output                      alu_ctrl_unsign ,
    output [5:0]    alu_inst_id     , // Instruction ID                   
    // ALU operation 
    output [31:0]               alu_op1_val     ,
    output [31:0]               alu_op2_val     ,
    // the result of ALU will commit to the ROB ,and bypass to other FU concurrently
    input                       alu_resp_vld    ,
    input  [31:0]               alu_resp_rd_val ,    
    input  [5:0]    alu_resp_inst_id,
    // ==========================================================================
    //BRU Interface
    output                      bru_req         ,
    output [5:0]    bru_inst_id     , // Instruction ID  
    output                      bru_ctrl_beq    ,
    output                      bru_ctrl_bne    ,
    output                      bru_ctrl_blt    ,
    output                      bru_ctrl_bge    ,
    output                      bru_ctrl_jal    ,
    output                      bru_ctrl_jalr   ,
    //BRU Operation Num
    output [31:0]               bru_pc_data     ,
    output [31:0]               bru_op1_val     ,
    output [31:0]               bru_op2_val     ,
    output                      bru_rd_vld      ,
    output [31:0]               bru_imm_val     ,    
    output [31:0]               bru_bp_taddr    , // bp target addr
    output                      bru_bp_taken    , // bp taken
    output [3:0]                bru_bp_bhtv     , // BHT Entry Value
    output [31:0]               bru_bp_phtv     , // PHT Entry Value    
    //BRU Response
    input  [5:0]    bru_resp_inst_id,
    input                       bru_resp_vld    ,
    input                       bru_resp_rd_vld ,
    input  [31:0]               bru_resp_rd_val ,    
    // ==========================================================================
    //LSU Interface                             
    output                      lsu_req         ,
    output                      lsu_ctrl_unsign ,
    output                      lsu_ctrl_load   ,
    output                      lsu_ctrl_store  ,
    output                      lsu_ctrl_word   ,
    output                      lsu_ctrl_half   ,
    output                      lsu_ctrl_byte   ,
    output [5:0]    lsu_inst_id     , // Instruction ID  
    //Store Instruction Retire 
    output                      lsu_stor_retire ,
    output [5:0]    lsu_stor_rid    ,   

    //LSU Operation Number
    output [31:0]               lsu_op1_val     ,
    output [31:0]               lsu_op2_val     ,    
    output [31:0]               lsu_store_data  ,
    //LSU Response
    input  [5:0]    lsu_resp_inst_id,
    input                       lsu_resp_vld    ,
    input                       lsu_resp_rd_vld ,
    input  [31:0]               lsu_resp_rd_val , //rd value    
    input                       lsu_exp_vld     ,  //ignore it when exception feature is not implemented
    input                       lsu_ready       ,
    //
    // ==========================================================================
    //MDU Port 
    //TODO
    //CSR Port Interface
    //TODO
    //Retire Operation
    output                      ret_flush_rles  , //Flush Release
    
    output                      ret_rd_req      ,
    output [5:0]    ret_inst_id     
);

//ISQ Port Connection
wire                      isq_ready       ; // Issue Queue Ready , when issue queue is full , isq_ready will be pull up
//Regfile Interface
wire [4:0]                rf_rs1_ind      ;
wire [31:0]               rf_rs1_data     ;
wire [4:0]                rf_rs2_ind      ;
wire [31:0]               rf_rs2_data     ;
wire [4:0]                ret_rd_ind      ;
wire [31:0]               ret_rd_data     ;

//ROB Interface
wire [5:0]    rob_rs1_ind     ;
wire [31:0]               rob_rs1_data    ;
wire [5:0]    rob_rs2_ind     ;
wire [31:0]               rob_rs2_data    ;

//ROB Port Connection
wire                      rob_flush_stall ;
wire                      rob_entry_full  ;
//ROB Write Request Interface
wire                      rob_wreq        ;
wire                      rob_wrd_vld     ;
wire                      rob_wt_store    ; //is Store?
// wire                      rob_ready       ;

// assign rob_reayd    =

assign isu_ready    = isq_ready && ~rob_flush_stall && ~rob_entry_full;
assign rob_wreq     = isq_wreq;
assign rob_wrd_vld  = isq_rd_vld;
assign rob_wt_store = isq_lsu_store;

frv_issue_queue _frv_issue_queue(
    .clk                (clk            ),
    .rst_n              (rst_n          ),
    .pd_rst             (pd_rst         ),
    .exp_flush          (exp_flush      ), // Exception Flush
    .exp_flush_tid      (exp_flush_tid  ), // Exception Flush ID
    .bru_flush          (bru_flush      ), // Branch Prediction failed Flush
    .isq_ready          (isq_ready      ), // Issue Queue Ready , when issue queue is full , isq_ready will be pull up
    .isq_wreq           (isq_wreq       ), // Issue Queue Request
    .isq_inst_data      (isq_inst_data  ),
    .isq_exp_vld        (isq_exp_vld    ),
    .isq_exp_code       (isq_exp_code   ),
    .isq_pc_data        (isq_pc_data    ),
    .isq_inst_id        (isq_inst_id    ), // Branch Prediction Flush ID
    .isq_alu_vld        (isq_alu_vld    ),
    .isq_alu_land       (isq_alu_land   ),
    .isq_alu_lor        (isq_alu_lor    ),
    .isq_alu_lxor       (isq_alu_lxor   ),
    .isq_alu_sll        (isq_alu_sll    ),
    .isq_alu_srl        (isq_alu_srl    ),
    .isq_alu_sra        (isq_alu_sra    ),
    .isq_alu_add        (isq_alu_add    ),
    .isq_alu_sub        (isq_alu_sub    ),
    .isq_alu_slt        (isq_alu_slt    ),
    .isq_alu_unsign     (isq_alu_unsign ),
    .isq_bru_vld        (isq_bru_vld    ),
    .isq_bru_beq        (isq_bru_beq    ),
    .isq_bru_bne        (isq_bru_bne    ),
    .isq_bru_blt        (isq_bru_blt    ),
    .isq_bru_bge        (isq_bru_bge    ),
    .isq_bru_jal        (isq_bru_jal    ),
    .isq_bru_jalr       (isq_bru_jalr   ),
    .isq_bp_taddr       (isq_bp_taddr   ), // bp target addr
    .isq_bp_taken       (isq_bp_taken   ), // bp taken
    .isq_bp_bhtv        (isq_bp_bhtv    ), // BHT Entry Value
    .isq_bp_phtv        (isq_bp_phtv    ), // PHT Entry Value
    .isq_lsu_vld        (isq_lsu_vld    ),
    .isq_lsu_unsign     (isq_lsu_unsign ),
    .isq_lsu_load       (isq_lsu_load   ),
    .isq_lsu_store      (isq_lsu_store  ),
    .isq_lsu_word       (isq_lsu_word   ),
    .isq_lsu_half       (isq_lsu_half   ),
    .isq_lsu_byte       (isq_lsu_byte   ),
    .isq_csr_vld        (isq_csr_vld    ),
    .isq_csr_write      (isq_csr_write  ),
    .isq_csr_set        (isq_csr_set    ),
    .isq_csr_clr        (isq_csr_clr    ), // CSR Clear
    .isq_rs1_vld        (isq_rs1_vld    ),
    .isq_rs1_rdy        (isq_rs1_rdy    ),
    .isq_rs1_ind        (isq_rs1_ind    ),
    .isq_rs1_type       (isq_rs1_type   ),
    .isq_rs2_vld        (isq_rs2_vld    ),
    .isq_rs2_rdy        (isq_rs2_rdy    ),
    .isq_rs2_ind        (isq_rs2_ind    ),
    .isq_rs2_type       (isq_rs2_type   ),
    .isq_imm_vld        (isq_imm_vld    ),
    .isq_imm_data       (isq_imm_data   ), // here we can compress the width
    .isq_rd_vld         (isq_rd_vld     ),
    // .isq_rdm_ind        (isq_rdm_ind    ),
    .isq_pc_used        (isq_pc_used    ), // jal and auipc will use the pc value    
    .alu_req            (alu_req        ),
    .alu_ctrl_land      (alu_ctrl_land  ),
    .alu_ctrl_lor       (alu_ctrl_lor   ),
    .alu_ctrl_lxor      (alu_ctrl_lxor  ),
    .alu_ctrl_sll       (alu_ctrl_sll   ),
    .alu_ctrl_srl       (alu_ctrl_srl   ),
    .alu_ctrl_sra       (alu_ctrl_sra   ),
    .alu_ctrl_add       (alu_ctrl_add   ),
    .alu_ctrl_sub       (alu_ctrl_sub   ),
    .alu_ctrl_slt       (alu_ctrl_slt   ),
    .alu_ctrl_unsign    (alu_ctrl_unsign),
    .alu_inst_id        (alu_inst_id    ), // Instruction ID                   
    .alu_op1_val        (alu_op1_val    ),
    .alu_op2_val        (alu_op2_val    ),
    .alu_fwd_vld        (alu_resp_vld    ),
    .alu_fwd_val        (alu_resp_rd_val ),    
    .alu_fwd_inst_id    (alu_resp_inst_id) ,    
    .bru_req            (bru_req        ),
    .bru_ctrl_beq       (bru_ctrl_beq   ),
    .bru_ctrl_bne       (bru_ctrl_bne   ),
    .bru_ctrl_blt       (bru_ctrl_blt   ),
    .bru_ctrl_bge       (bru_ctrl_bge   ),
    .bru_ctrl_jal       (bru_ctrl_jal   ),
    .bru_ctrl_jalr      (bru_ctrl_jalr  ),
    .bru_inst_id        (bru_inst_id    ), // Instruction ID  
    .bru_pc_data        (bru_pc_data    ),
    .bru_op1_val        (bru_op1_val    ),
    .bru_op2_val        (bru_op2_val    ),
    .bru_imm_val        (bru_imm_val    ),
    .bru_rd_vld         (bru_rd_vld     ),
    .bru_bp_taddr       (bru_bp_taddr   ), // bp target addr
    .bru_bp_taken       (bru_bp_taken   ), // bp taken
    .bru_bp_bhtv        (bru_bp_bhtv    ), // BHT Entry Value
    .bru_bp_phtv        (bru_bp_phtv    ), // PHT Entry Value  
    .bru_fwd_vld        (bru_resp_vld    ),
    .bru_fwd_inst_id    (bru_resp_inst_id),
    .bru_fwd_rd_vld     (bru_resp_rd_vld ),
    .bru_fwd_val        (bru_resp_rd_val ),                                    
    .lsu_ready          (lsu_ready      ),
    .lsu_req            (lsu_req        ),
    .lsu_ctrl_unsign    (lsu_ctrl_unsign),
    .lsu_ctrl_load      (lsu_ctrl_load  ),
    .lsu_ctrl_store     (lsu_ctrl_store ),
    .lsu_ctrl_word      (lsu_ctrl_word  ),
    .lsu_ctrl_half      (lsu_ctrl_half  ),
    .lsu_ctrl_byte      (lsu_ctrl_byte  ),
    .lsu_inst_id        (lsu_inst_id    ), // Instruction ID  
    .lsu_op1_val        (lsu_op1_val    ),
    .lsu_op2_val        (lsu_op2_val    ),    
    .lsu_store_data     (lsu_store_data ),
    .lsu_fwd_inst_id    (lsu_resp_inst_id),
    .lsu_fwd_vld        (lsu_resp_vld    ),
    .lsu_fwd_rd_vld     (lsu_resp_rd_vld ),
    .lsu_fwd_val        (lsu_resp_rd_val ), //rd value    
    .lsu_exp_vld        (lsu_exp_vld    ),  //ignore it when exception feature is not implemented
    .rf_rs1_ind         (rf_rs1_ind     ),
    .rf_rs1_data        (rf_rs1_data    ),
    .rf_rs2_ind         (rf_rs2_ind     ),
    .rf_rs2_data        (rf_rs2_data    ),
    .rob_rs1_ind        (rob_rs1_ind    ),
    .rob_rs1_data       (rob_rs1_data   ),
    .rob_rs2_ind        (rob_rs2_ind    ),
    .rob_rs2_data       (rob_rs2_data   )
);


frv_isu_rob _frv_isu_rob(
.clk                            (clk             ),
.rst_n                          (rst_n           ),
.pd_rst                         (pd_rst          ),
.ret_flush_rles                 (ret_flush_rles  ), //Flush Release
.rob_flush_stall                (rob_flush_stall ),
.rob_entry_full                 (rob_entry_full  ),
.rob_wreq                       (rob_wreq        ),
.rob_wrd_vld                    (rob_wrd_vld     ),
.rob_wrd_ind                    (isq_rd_ind      ),
.rob_wt_store                   (rob_wt_store    ), //is Store?
.rob_exp_req                    (1'b0            ),
.ret_rd_req                     (ret_rd_req      ),
.ret_rd_data                    (ret_rd_data     ),
.ret_rd_ind                     (ret_rd_ind      ),
.ret_inst_id                    (ret_inst_id     ),
.lsu_stor_retire                (lsu_stor_retire ),
.lsu_stor_rid                   (lsu_stor_rid    ),    
.alu_resp_vld                   (alu_resp_vld    ),
.alu_resp_rd_val                (alu_resp_rd_val ),    
.alu_resp_inst_id               (alu_resp_inst_id),        
.bru_resp_inst_id               (bru_resp_inst_id),
.bru_resp_vld                   (bru_resp_vld    ),
.bru_resp_rd_vld                (bru_resp_rd_vld ),
.bru_resp_rd_val                (bru_resp_rd_val ),
.bru_flush                      (bru_flush       ),
.lsu_flush                      (1'b0            ),     
.lsu_resp_inst_id               (lsu_resp_inst_id),
.lsu_resp_vld                   (lsu_resp_vld    ),
.lsu_resp_rd_vld                (lsu_resp_rd_vld ),
.lsu_resp_rd_val                (lsu_resp_rd_val ), //rd value    
.rob_rs1_ind                    (rob_rs1_ind[5-1:0]   ),
.rob_rs2_ind                    (rob_rs2_ind[5-1:0]   ),
.rob_rs1_data                   (rob_rs1_data    ),
.rob_rs2_data                   (rob_rs2_data    )
// .rob_winst_id                   (rob_winst_id    )
);

frv_regfile _frv_regfile(
.clk             (clk        ),
.rst_n           (rst_n      ),
.pd_rst          (pd_rst     ),
.rf_rs1_ind      (rf_rs1_ind ),
.rf_rs1_data     (rf_rs1_data), // rs1 data
.rf_rs2_ind      (rf_rs2_ind ),
.rf_rs2_data     (rf_rs2_data), // rs2 data
.ret_rd_req      (ret_rd_req ),
.ret_rd_ind      (ret_rd_ind ),
.ret_rd_data     (ret_rd_data) // commit index
);


endmodule


